package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;


@Service
public class MovementServiceImpl implements MovementService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    /**
     * 保存动态
     * 1.往动态详情添加一条数据（完整记录）
     * 2.往自己的动态表中添加一条记录（只有动态id）
     * 3.查询好友关系
     * 4.往好友的朋友圈中加入一条记录（动态id和UserId 发布人id）
     * @param movement
     * @return
     */
    @Override
    public ObjectId saveMovement(Movement movement) {
        //1.先向动态表中插入动态信息，获取到动态的id
        //设置动态大数据要使用的id
        movement.setPid(idService.getNextId(ConstantUtil.MOVEMENT_ID));//mongo自增id
        mongoTemplate.save(movement); //保存动态MongoDB保存完数据    主键会自动返回
        ObjectId movementId = movement.getId();//自动返回的动态id
        //2.向自己的动态表中写入动态的id
        MyMovement myMovement = new MyMovement();
        myMovement.setCreated(System.currentTimeMillis());//时间
        myMovement.setPublishId(movementId);//动态的id
        mongoTemplate.save(myMovement, ConstantUtil.MOVEMENT_MINE + movement.getUserId());
        //3.查找好友关系
        //  封装查询条件  查询我的好友
        Query query = new Query(
                Criteria.where("userId").is(movement.getUserId())
        );
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        //4.遍历好友，向好友的朋友表中写入（动态id  userId和发布人id）
        if (CollectionUtil.isNotEmpty(friendList)) {//新注册用户可能没有好友
            for (Friend friend : friendList) {
                //得到一个朋友的id
                Long friendId = friend.getFriendId();
                //构建朋友动态表对象
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setUserId(movement.getUserId());//发动态人的id
                friendMovement.setPublishId(movementId);//动态的id
                friendMovement.setCreated(System.currentTimeMillis());
                //向好友的朋友表中写入动态id
                mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND + friendId);
            }
        }


        return movementId;
    }

    /**
     * 查询个人动态
     * 1.根据用户的id先找个人动态表 将动态的id查询出来
     * 2.通过动态的id循环遍历获得数据
     * 3.查询总记录数
     * 4.返回PageBeanVo
     */
    @Override
    public PageBeanVo findMyMovement(Integer pageNumber, Integer pageSize, Long userId) {
        //1.根据用户的id先找个人动态表  将动态的id查询出来
        //计算开始索引
        int startIndex = (pageNumber - 1) * pageSize;
        Query query = new Query().with(Sort.by(Sort.Order.desc("created")))//时间降序
                .skip(startIndex).limit(pageSize);//分页数据
        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        //提前定义好存储动态集合数据
        List<Movement> list = new ArrayList<>();
        //2.通过动态的id循环遍历获得数据
        if (CollectionUtil.isNotEmpty(myMovementList)) {
            for (MyMovement myMovement : myMovementList) {
                //动态详情对象
                Movement movement = mongoTemplate.findById(myMovement.getPublishId(), Movement.class);
                if (movement.getState()==1) {//状态已审核的   才展示
                    list.add(movement);
                }
            }
        }
        //3.查询总记录数
        long counts = mongoTemplate.count(query, ConstantUtil.MOVEMENT_MINE + userId);
        //4.返回PageBeanVo
        ;

        return new PageBeanVo(pageNumber, pageSize, counts, list);
    }

    /**
     *查询当前用户的好友动态数据
     */
    @Override
    public PageBeanVo findFriendMovements(Integer pageNumber, Integer pageSize, Long userId) {
        //1.根据用户的id先找朋友圈表，目的查询出朋友圈动态    动态id值
        //计算开始索引
        int startIndex = (pageNumber - 1) * pageSize;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))//时间降序
                .skip(startIndex).limit(pageSize);//分页数据
        List<FriendMovement> friendMovements = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);
        //提前定义存储数据的动态集合数据
        List<Movement> list = new ArrayList<>();
        //2.通过动态的id循环遍历获得数据
        if (CollectionUtil.isNotEmpty(friendMovements)) {
            for (FriendMovement friendMovement : friendMovements) {
                //动态详情对象
                Movement movement = mongoTemplate.findById(friendMovement.getPublishId(), Movement.class);
                if (movement.getState()==1) {//状态已审核的   才展示
                    list.add(movement);
                }
            }
        }
        //4.查询总记录数
        long counts = mongoTemplate.count(query, ConstantUtil.MOVEMENT_FRIEND + userId);
        //3.返回pageBeanVo

        return new PageBeanVo(pageNumber,pageSize,counts,list);
    }
    //查询推荐的动态
    @Override
    public PageBeanVo findRecommendMovement(Long userId, Integer pageNumber, Integer pageSize) {
        //计算起始索引
        int startIndex = (pageNumber - 1) * pageSize;
        //1.从推荐动态表根据被推荐用户id分页查询，得到动态id集合
        Query query = new Query(Criteria.where("userId").is(userId)).with(Sort.by(Sort.Order.desc("score")))
                .skip(startIndex).limit(pageSize);

        List<RecommendMovement> recommendMovements = mongoTemplate.find(query, RecommendMovement.class);
        //定义存储推荐动态集合的集合数据
        List<Movement> movementList = new ArrayList<>();
        //2.遍历动态id集合，根据动态id去动态详情表中查询详情
        if (CollectionUtil.isNotEmpty(recommendMovements)) {
            for (RecommendMovement recommendMovement : recommendMovements) {
                //推荐动态的id
                ObjectId movementId = recommendMovement.getPublishId();
                //根据动态id去动态详情表中查询详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);
                if (movement.getState() == 1) {//判断动态是否审核通过,通过则添加到被推荐动态集合
                    movementList.add(movement);

                }

            }
        }
        //3.统计总记录数据
        long counts = mongoTemplate.count(query, RecommendMovement.class);
        //4.返回分页vo

        return new PageBeanVo(pageNumber,pageSize,counts,movementList);
    }

    /**
     * 根据id查询动态详情
     * @param movementId
     * @return
     */
    @Override
    public Movement findMovementById(String movementId) {

        return mongoTemplate.findById(movementId, Movement.class);
    }

    /**
     * 分页查询动态数据
     */
    @Override
    public PageBeanVo findMovementsByUserIdAndState(Integer pageNumber, Integer pageSize, Long uid, Integer stateInt) {
        int startIndex = (pageNumber - 1) * pageSize;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip(startIndex).limit(pageSize);
        if (uid != null) {//动态拼接条件
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (stateInt != null) {//拼接动态条件
            query.addCriteria(Criteria.where("state").is(stateInt));
        }
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);
        long count = mongoTemplate.count(query, Movement.class);
        return new PageBeanVo(pageNumber, pageSize, count, movementList);
    }

    /**
     * 修改动态
     * @param movement
     */
    @Override
    public void updateMovement(Movement movement) {
        mongoTemplate.save(movement);//有就是修改    没有就是保存
    }

    @Override
    public Boolean auditMovementIfPass(String movementId, Boolean option) {
        //设置返回值
        Boolean result;
        //根据id查询动态详情
        Query query = new Query(
                Criteria.where("id").is(new ObjectId(movementId))
        );
        Movement movement = mongoTemplate.findOne(query, Movement.class);
        //通过
        if (option) {
            //设置审核状态为   1   已审核
            movement.setState(1);
            result = true;
        } else {
            //不通过 设置审核状态为   2   已驳回
            movement.setState(2);
            result = false;
        }
        mongoTemplate.save(movement);

        return result;
    }


}
